﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using sccmclictr.automation;
using Microsoft.SystemCenter.Orchestrator.Integration;
using System.Management;


namespace OpalisAddOn.Updates
{
    /// <summary>
    /// Re-Deploy Security Updates (Re-Evaluation)
    /// </summary>
    [Activity("Update Deployment", Description="Deploy authorized Software updates...")]
    public class UpdateDeploy
    {
        private String targetComputer;
        private String userName;
        private string password;

        [ActivityInput]
        public String TargetComputer
        {
            set { targetComputer = value; }
        }

        [ActivityInput(Optional = true)]
        public String UserName
        {
            set { userName = value; }
        }

        [ActivityInput(Optional = true, PasswordProtected = true)]
        public String Password
        {
            set { password = value; }
        }


        [ActivityMethod]
        public void Invoke()
        {
            try
            {
                SCCMAgent oClient;
                if (string.IsNullOrEmpty(userName))
                {
                    oClient = new SCCMAgent(targetComputer);
                }
                else
                {
                    oClient = new SCCMAgent(targetComputer, userName, password);
                }

                //oClient.Client.AgentActions.ForceUpdateScan();
                oClient.Client.SoftwareUpdates.InstallAllApprovedUpdates();

                oClient.disconnect();
            }
            catch (Exception ex)
            {
                throw new ActivityWarning(ex.Message);
            }
        }
    }

    [Activity("Deploy Articles", Description = "Install all KB-Articles from the comma-separeted input (Updates must be assigned in CM12)...")]
    public class UpdateArticleDeploy
    {
        private String targetComputer;
        private String userName;
        private string password;
        private List<string> kBArticles;

        [ActivityInput]
        public String TargetComputer
        {
            set { targetComputer = value; }
        }

        [ActivityInput]
        public String KBArticles
        {
            set { kBArticles = new List<string>(value.Split(',')); }
        }

        [ActivityInput(Optional = true)]
        public String UserName
        {
            set { userName = value; }
        }

        [ActivityInput(Optional = true, PasswordProtected = true)]
        public String Password
        {
            set { password = value; }
        }

        [ActivityMethod]
        public void Invoke()
        {
            try
            {
                SCCMAgent oClient;
                if (string.IsNullOrEmpty(userName))
                {
                    oClient = new SCCMAgent(targetComputer);
                }
                else
                {
                    oClient = new SCCMAgent(targetComputer, userName, password);
                }

                //Generate a List of all Updates with the specified KB Articles...
                List<sccmclictr.automation.functions.softwareupdates.CCM_SoftwareUpdate> oUpds = oClient.Client.SoftwareUpdates.SoftwareUpdateReload.Where(t => kBArticles.Contains(t.ArticleID)).ToList();

                //Install all the Updates
                if (oUpds.Count > 0)
                {
                    oClient.Client.SoftwareUpdates.InstallUpdates(oUpds);
                }

                oClient.disconnect();
            }
            catch (Exception ex)
            {
                throw new ActivityWarning(ex.Message);
            }
        }
    }

    [Activity("Deploy Update IDs", Description = "Install all Update-ID's from the comma-separeted input (Updates must be assigned in CM12)...")]
    public class UpdateIDDeploy
    {
        private String targetComputer;
        private String userName;
        private string password;
        private List<string> updateIDs;

        [ActivityInput]
        public String TargetComputer
        {
            set { targetComputer = value; }
        }

        [ActivityInput]
        public String UpdateIDs
        {
            set { updateIDs = new List<string>(value.Split(',')); }
        }

        [ActivityInput(Optional = true)]
        public String UserName
        {
            set { userName = value; }
        }

        [ActivityInput(Optional = true, PasswordProtected = true)]
        public String Password
        {
            set { password = value; }
        }

        [ActivityMethod]
        public void Invoke()
        {
            try
            {
                SCCMAgent oClient;
                if (string.IsNullOrEmpty(userName))
                {
                    oClient = new SCCMAgent(targetComputer);
                }
                else
                {
                    oClient = new SCCMAgent(targetComputer, userName, password);
                }

                //Generate a List of all Updates with the specified UpdateID's...
                List<sccmclictr.automation.functions.softwareupdates.CCM_SoftwareUpdate> oUpds = oClient.Client.SoftwareUpdates.SoftwareUpdateReload.Where(t => updateIDs.Contains(t.UpdateID)).ToList();

                //Install all the Updates
                if (oUpds.Count > 0)
                {
                    oClient.Client.SoftwareUpdates.InstallUpdates(oUpds);
                }

                oClient.disconnect();
            }
            catch (Exception ex)
            {
                throw new ActivityWarning(ex.Message);
            }
        }
    }

    /// <summary>
    /// Scan for Security Updates
    /// </summary>
    [Activity("Update Scan", Description="Scan for missing software updates...")]
    public class UpdateScan
    {
        private String targetComputer;
        private String userName;
        private string password;

        [ActivityInput]
        public String TargetComputer
        {
            set { targetComputer = value; }
        }

        [ActivityInput(Optional = true)]
        public String UserName
        {
            set { userName = value; }
        }

        [ActivityInput(Optional = true, PasswordProtected = true)]
        public String Password
        {
            set { password = value; }
        }

        [ActivityMethod]
        public void Invoke()
        {
            try
            {
                SCCMAgent oClient;
                if (string.IsNullOrEmpty(userName))
                {
                    oClient = new SCCMAgent(targetComputer);
                }
                else
                {
                    oClient = new SCCMAgent(targetComputer, userName, password);
                }

                oClient.Client.AgentActions.ForceUpdateScan();

                oClient.disconnect();
            }
            catch (Exception ex)
            {
                throw new ActivityWarning(ex.Message);
            }
        }
    }

    /// <summary>
    /// Check if Pacth-Reboot is pending
    /// </summary>
    [Activity("Reboot Pending", Description="Check if a reboot is pending...")]
    public class WUAReboot
    {
        private String targetComputer;
        private String userName;
        private string password;
        private Boolean rebootPending;

        [ActivityInput]
        public String TargetComputer
        {
            set { targetComputer = value; }
        }

        [ActivityInput(Optional = true)]
        public String UserName
        {
            set { userName = value; }
        }

        [ActivityInput(Optional = true, PasswordProtected = true)]
        public String Password
        {
            set { password = value; }
        }

        [ActivityOutput("Reboot Pending", Description = "True = A Reboot is required")]
        public Boolean RebootPending
        {
            get { return rebootPending; }
        }

        [ActivityMethod]
        public void Invoke()
        {
            try
            {
                SCCMAgent oClient;
                if (string.IsNullOrEmpty(userName))
                {
                    oClient = new SCCMAgent(targetComputer);
                }
                else
                {
                    oClient = new SCCMAgent(targetComputer, userName, password);
                }

                bool bResult = false;
                if (oClient.Client.AgentProperties.RebootPending())
                    bResult = true;
                if (oClient.Client.SoftwareUpdates.UpdateWithPendingReboot())
                    bResult = true;
                if (oClient.Client.AgentProperties.FileRenameOperationsPending)
                    bResult = true;

                rebootPending = bResult;

                oClient.disconnect();
            }
            catch (Exception ex)
            {
                throw new ActivityWarning(ex.Message);
            }
        }
    }

    /// <summary>
    /// Check if File-Rename Operation is pending
    /// </summary>
    [Activity("File rename operation pending", Description="Check if file rename operations are pending...")]
    public class FileRename
    {
        private String targetComputer;
        private String userName;
        private string password;
        private Boolean renamePending;

        [ActivityInput]
        public String TargetComputer
        {
            set { targetComputer = value; }
        }

        [ActivityInput(Optional = true)]
        public String UserName
        {
            set { userName = value; }
        }

        [ActivityInput(Optional = true, PasswordProtected = true)]
        public String Password
        {
            set { password = value; }
        }

        [ActivityOutput("Rename Pending", Description = "True = File rename operation is pending")]
        public Boolean RenamePending
        {
            get { return renamePending; }
        }

        [ActivityMethod]
        public void Invoke()
        {
            try
            {
                SCCMAgent oClient;
                if (string.IsNullOrEmpty(userName))
                {
                    oClient = new SCCMAgent(targetComputer);
                }
                else
                {
                    oClient = new SCCMAgent(targetComputer, userName, password);
                }

                renamePending = false;
                renamePending = oClient.Client.AgentProperties.FileRenameOperationsPending;
                
                oClient.disconnect();
            }
            catch (Exception ex)
            {
                throw new ActivityWarning(ex.Message);
            }
        }
    }

    /// <summary>
    /// Check missing security updates
    /// </summary>
    [Activity("Missing Security Updates", Description="Check for missing authorized security patches...")]
    public class MissingPatches
    {
        private String targetComputer;
        private String userName;
        private string password;
        private List<string> missingArticles;
        private List<string> missingUpdateIDs;
        private Boolean patchesMissing;
        private Boolean patchErrors;
        private Boolean patchRunning;

        [ActivityInput]
        public String TargetComputer
        {
            set { targetComputer = value; }
        }

        [ActivityInput(Optional = true)]
        public String UserName
        {
            set { userName = value; }
        }

        [ActivityInput(Optional = true, PasswordProtected = true)]
        public String Password
        {
            set { password = value; }
        }

        [ActivityOutput("Patch Missing", Description = "True = Approved Patches are missing")]
        public Boolean PatchesMissing
        {
            get { return patchesMissing; }
        }

        [ActivityOutput("Patch Errors", Description = "True = Approved Patches with Errors during installtion")]
        public Boolean PatchesErrors
        {
            get { return patchErrors; }
        }

        [ActivityOutput("Patch installation running", Description = "True = Approved Patches installation is running")]
        public Boolean PatchesRunning
        {
            get { return patchRunning; }
        }

        [ActivityOutput("Missing patches...", Description = "List of missing Articles")]
        public List<string> MissingArticles
        {
            get { return missingArticles; }
        }

        [ActivityOutput("Missing UpdateIDs...", Description = "List of missing UpdateIDs")]
        public List<string> MissingUpdateIDs
        {
            get { return missingUpdateIDs; }
        }

        [ActivityMethod]
        public void Invoke()
        {
            SCCMAgent oClient;
            if (string.IsNullOrEmpty(userName))
            {
                oClient = new SCCMAgent(targetComputer);
            }
            else
            {
                oClient = new SCCMAgent(targetComputer, userName, password);
            }
            
            //Get all SW Updates
            List<sccmclictr.automation.functions.softwareupdates.CCM_SoftwareUpdate> lSWUpdates = oClient.Client.SoftwareUpdates.SoftwareUpdateReload;
            missingArticles = lSWUpdates.FindAll(t => (t.ComplianceState == 0) | (t.ComplianceState == 13) | (t.ComplianceState == 21)).ConvertAll(t => t.ArticleID);
            missingUpdateIDs = lSWUpdates.FindAll(t => (t.ComplianceState == 0) | (t.ComplianceState == 13) | (t.ComplianceState == 21)).ConvertAll(t => t.UpdateID);
            patchesMissing = false;
            patchErrors = false;
            patchRunning = false;

            if (oClient.Client.SoftwareUpdates.SoftwareUpdateReload.Count > 0)
                patchesMissing = true;
            if (oClient.Client.SoftwareUpdates.UpdateInstallationErrors())
                patchErrors = true;
            if (oClient.Client.SoftwareUpdates.UpdateInstallationRunning())
                patchRunning = true;

            oClient.disconnect();

        }
    }

}

